package com.sheng.project.utils;

import cn.hutool.core.lang.tree.TreeNode;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.GsonBuilder;
import com.google.gson.LongSerializationPolicy;
import com.google.gson.reflect.TypeToken;
import lombok.experimental.UtilityClass;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
 * JSONUtil扩展工具类
 *
 * @author liusheng
 * @date 2022/09/07
 */
@UtilityClass
public class JSONUtil extends cn.hutool.json.JSONUtil {

    /**
     * 对象转 JSON 字符串，所有 Long 转 String
     *
     * @param src 对象
     * @return JSON
     */
    public String long2StringJsonStr(Object src) {
        return new GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.STRING).create().toJson(src);
    }

    /**
     * 对象转 TreeNode 扩展字段 Map
     *
     * @param src 转换对象
     * @return 扩展字段 Map
     */
    public Map<String, Object> toTreeNodeExtra(Object src) {
        List<String> treeNodeFieldNames = new ArrayList<>();
        Stream.of(TreeNode.class.getDeclaredFields()).forEach(treeNode -> treeNodeFieldNames.add(treeNode.getName()));
        return toBean(new GsonBuilder()
                .setLongSerializationPolicy(LongSerializationPolicy.STRING)
                //忽略 TreeNode 字段
                .setExclusionStrategies(new ExclusionStrategy() {
                    @Override
                    public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                        return treeNodeFieldNames.contains(fieldAttributes.getName());
                    }

                    @Override
                    public boolean shouldSkipClass(Class<?> aClass) {
                        return false;
                    }
                }).create().toJson(src), new TypeToken<Map<String, Object>>() {
        }.getType(), false);
    }
}
